home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / shell / ncd-0.000 / ncd-0 / ncd-0.9.8 / dirs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-06  |  3.9 KB  |  179 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4.  
  5. #include "ncd.h"
  6.  
  7. /*************************************************************************/
  8. /* adds the final slash to {dirName} if necessary.   {returns} the same
  9.    {dirName} */
  10.  
  11. char *addSlash(char *dirName)
  12. {
  13.     size_t len;
  14.  
  15.     len = strlen(dirName);
  16.     if ((!len) || (dirName[len - 1] != '/')) {
  17.         dirName[len + 1] = 0;
  18.         dirName[len] = '/';
  19.     }
  20.     return dirName;
  21. }
  22.  
  23. /*************************************************************************/
  24. /* strips the final slash from {dirName} if necessary.  {returns} the same
  25.    {dirName} */
  26.  
  27. char *stripSlash(char *dirName)
  28. {
  29.     size_t len;
  30.  
  31.     len = strlen(dirName);
  32.     if ((len > 1) && (dirName[len - 1] == '/'))
  33.         dirName[len - 1] = '\0';
  34.  
  35.     return dirName;
  36. }
  37.  
  38. /*************************************************************************/
  39. /* preprocesses {absDirName}, that must be a complete directory (starting
  40.    with a slash), otherwise, the function {returns} NULL. The
  41.    preprocessing consists on:
  42.  
  43.    - adding a final slash if necessary (/home/smith -> /home/smith/)   
  44.  
  45.    - stripping all sequences of two or more contiguos slashes
  46.    (/home//smith/ -> /home/smith/)
  47.  
  48.    - evaluating all /../ sequences (/home/smith/../ -> /home/)
  49.  
  50.    The function {returns} the same preprocessed {absDirName}. */
  51.  
  52. char *compactAbsDir(char *absDirName)
  53. {
  54.     char *s, *ss;
  55.  
  56.     if ((*absDirName != 0) && (*absDirName != '/'))
  57.         return NULL;
  58.  
  59.     addSlash(absDirName);
  60.  
  61.     while ((s = strstr(absDirName, "//")) != NULL)
  62.         strcpy(s, s + 1);
  63.  
  64.     while ((s = strstr(absDirName, "/../")) != NULL) {
  65.         *s = 0;
  66.         ss = strrchr(absDirName, '/');
  67.         if (ss != NULL)
  68.             strcpy(ss, s + 3);
  69.         else
  70.             strcpy(absDirName, s + 3);
  71.     }
  72.  
  73.     return absDirName;
  74. }
  75.  
  76. /*************************************************************************/
  77. /* converts the absolute directory {dir} in the actual physicall
  78.    directory, substituting all the possible soft links, and also  adds the 
  79.  
  80.    final slash if necessary.
  81.  
  82.    {dir} must be an absolute directory (star with slash), otherwise the
  83.    funcion return NULL.
  84.  
  85.    The funcion returns the same reconverted {dir}. {dir} must be PATH_MAX
  86.    chars long (or more) */
  87.  
  88. char *trueDir(char *dir)
  89. {
  90. /* limits the max. number of links. Needed for ill formed link series */
  91.  
  92.     char *s;
  93.     char stmp[PATH_MAX * 2];
  94.     char lnk[PATH_MAX];
  95.     char tpath[PATH_MAX*2];
  96.     int i;
  97.     int max;
  98.  
  99.     strcpy(stmp,dir);
  100.     if (compactAbsDir(stmp) == NULL)
  101.         return NULL;
  102.     addSlash(stmp);
  103.     tpath[0] = '/';
  104.     tpath[1] = '\0';
  105.     max = 0;
  106.     
  107.  
  108.     while (stmp[0]!='\0') {
  109.  
  110.         s = strchr(stmp,'/');
  111.         *s = '\0';
  112.         addSlash(tpath);
  113.         strcat(tpath,stmp);
  114.         strcpy(stmp,s+1);
  115.         
  116.         stripSlash(tpath);
  117.         i = readlink(tpath, lnk, PATH_MAX);
  118.         if (i > 0) {
  119.             max ++;
  120.             if (max>MAX_LINKS)
  121.                 return NULL;
  122.                 
  123.             lnk[i] = '\0';
  124.             if (lnk[0] == '/')
  125.                 strcpy(tpath, lnk);
  126.             else {
  127.                 addSlash(tpath);
  128.                 strcat(tpath, "../");
  129.                 strcat(tpath, lnk);
  130.             }
  131.             addSlash(tpath);
  132.             strcat(tpath,stmp);
  133.             compactAbsDir(tpath);
  134.             strcpy(stmp,tpath);
  135.             tpath[0] = '/';
  136.             tpath[1] = '\0';
  137.         }
  138.     }
  139.     strcpy(dir,tpath);
  140.  
  141.     return dir;
  142. }
  143.  
  144. /*************************************************************************/
  145. /* {returns} just the last subdirectory name (without the final slash), in 
  146.  
  147.    a malloc() allocated string (you must free() it!). In {dirPath} the
  148.    function receives a directory name, with or without the final slash. If 
  149.  
  150.    {dirPath} is the root directory ('/') the function returns '/'. */
  151.  
  152. char *getDirName(char *dirPath)
  153. {
  154.     char *s, *ss;
  155.     int slash;
  156.  
  157.     slash = ((*dirPath != '\0') && (dirPath[strlen(dirPath) - 1] == '/'));
  158.     if (slash)
  159.         stripSlash(dirPath);
  160.  
  161.     s = strrchr(dirPath, '/');
  162.     if ((s == NULL) || (s[1] == '\0'))
  163.         ss = strdup(dirPath);
  164.     else
  165.         ss = strdup(s + 1);
  166.  
  167.     if (ss == NULL) {
  168.         cleanUp();
  169.         fprintf(stderr, "error: no memory\n");
  170.         exit(1);
  171.     }
  172.     if (slash)
  173.         addSlash(dirPath);
  174.  
  175.     return ss;
  176. }
  177.  
  178. /*************************************************************************/
  179.